package cn.z2huo.usercenter.util;

import cn.hutool.crypto.digest.DigestUtil;
import cn.z2huo.usercenter.constant.SystemConstants;
import cn.z2huo.usercenter.enums.AppEnum;
import cn.z2huo.usercenter.enums.SystemEnum;
import cn.z2huo.usercenter.jackson.RedisJsonMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * <p>
 *
 * @author z2huo
 */
@Getter
@RequiredArgsConstructor
public enum RedisKeyGenerateUtils {

    DEFAULT(SystemConstants.CURRENT_SYSTEM, null),

    MANAGEMENT_APP(SystemConstants.CURRENT_SYSTEM, AppEnum.MANAGEMENT_APP),

    AUTHENTICATION_APP(SystemConstants.CURRENT_SYSTEM, AppEnum.AUTHENTICATION_APP),

    ;

    private final SystemEnum system;

    private final AppEnum app;

    private static final JsonMapper CACHE_JSON_MAPPER = RedisJsonMapper.INSTANCE;

    public String generateMd5(@Nonnull String resourceType, @Nullable String resourceCode, @Nullable Object... others) {
        return generateMd5(system, app, resourceType, resourceCode, others);
    }

    public static String generateMd5(@Nonnull SystemEnum systemCode, @Nullable AppEnum appCode, @Nonnull String resourceType,
                                     @Nullable String resourceCode, @Nullable Object... others) {
        String md5ParameterString = "";
        if (ArrayUtils.isNotEmpty(others)) {
            try {
                md5ParameterString = DigestUtil.md5Hex16(CACHE_JSON_MAPPER.writeValueAsBytes(others));
            } catch (JsonProcessingException e) {
                throw new RuntimeException("generate redis key fail", e);
            }
        }
        return String.format("%s:%s:%s",
                DigestUtil.md5Hex(appCode == null ? systemCode.getSystemCode() : systemCode + ":" + appCode.getAppCode()).substring(0, 8),
                DigestUtil.md5Hex16(StringUtils.isBlank(resourceCode) ? resourceType : resourceType + ":" + resourceCode),
                md5ParameterString);
    }

}
